package cn.hy.prac.service.orderpay;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

/**
 * 发起支付宝支付，调用支付宝相关借口
 * @author Administrator
 *
 */
@Service
public class AlipayService {

	
	//本工程的外网访问域名，支付宝异步回调和同步回调不允许本机自测
	//springboot自动注入，类似json格式填写
	@Value("${hy.hyPayDomain}")
	private String hyPayDomain;

	/** 支付宝合作ID */
	public static final String ALI_PARTNERID = "2088002765191003";
	/** 支付宝交易安全校验码 */
	public static final String ALI_KEY = "f0mkcvhbjua8jbpzt24gxmvl3kxr2lnf";
	/** 支付宝交互编码 */
	public static final String ENCODING_CHARSET = "UTF-8";
	/** 支付宝加密方式 */
	public static final String SIGN_TYPE = "MD5";
	
	/** 支付请求地址 */
	public static final String ALI_REQUEST_URL = "https://mapi.alipay.com/gateway.do";
	
	
	
	/**
	 * 获取支付宝支付url
	 * @author haoyi 
	 * @param paynum 支付号
	 * @param money 支付金额(分)
	 * @param subject 支付标题(用于在支付宝显示)
	 * @param isMobile 是否移动端
	 * @return
	 * @throws Exception
	 */
	public String getPayUrl(String paynum, int money, String subject, boolean isMobile) throws Exception{
		String moneyF = String.valueOf(Float.parseFloat(String.valueOf(money)) / 100); // 金额转换为元
		Map<String, String> params = new HashMap<String ,String>();
		params.put("service", isMobile ? "alipay.wap.create.direct.pay.by.user" : "create_direct_pay_by_user");	// 接口名称
		params.put("partner", ALI_PARTNERID); 								// 合作者身份ID, 以2088开头的纯16位数字。
		params.put("out_trade_no", paynum);									// 商户订单号
		params.put("subject", subject);												// 商品名称
		params.put("total_fee", moneyF);											// 该笔订单的资金总额，单位为元。取值范围为[0.01，100000000.00]，精确到小数点后两位。
		params.put("payment_type", "1");											// 支付类型	(1代表商品购买)
		params.put("seller_id", ALI_PARTNERID);								// 卖家支付宝用户号, 以2088开头的纯16位数字。
		
		//测试自己映射外网访问域名
		params.put("return_url", hyPayDomain+"/bpay/payReturn");	// 同步回调URL
		//暂时测试为www.baidu.com
		params.put("notify_url", "www.baidu.com");	// 异步通知URL
		params.put("_input_charset", ENCODING_CHARSET);			// URL 编码
		params.put("sign", getSign(params));		// 签名
		params.put("sign_type", SIGN_TYPE);	// 加密方式
		return packUrl(params);	
	}
	
	/**
	 * 获取支付宝签名
	 * @author haoyi 
	 * @param params
	 * @return
	 * @throws Exception
	 */
	public String getSign(Map<String, String> params) {
        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);		// key 排序
        StringBuffer prestr = new StringBuffer(); 
        String value;
        for (String key : keys) {
        	value = params.get(key);
        	if (key!=null && !key.equalsIgnoreCase("sign") && !key.equalsIgnoreCase("sign_type")
        			&& value!=null && !value.isEmpty()){
        		prestr.append(key).append("=").append(value).append("&");
        	}
        }
        prestr.deleteCharAt(prestr.length() - 1); // 去除最后一个&
        prestr.append(ALI_KEY); //  添加私钥  
        
        //加密方式为MD5加密，spring提供的MD5加密方式
        return DigestUtils.md5DigestAsHex(prestr.toString().getBytes());
    }
	
	/**
	 * 封装请求url参数,请求支付宝进行支付
	 * @param params
	 * @return
	 * @throws Exception 
	 */
	public String packUrl(Map<String, String> params) throws Exception{
		List<String> keys = new ArrayList<String>(params.keySet());	//获取参数key
		StringBuffer prestr = new StringBuffer(ALI_REQUEST_URL).append("?");
	    String value;
	    for (String key : keys) {
			value = URLEncoder.encode(params.get(key), ENCODING_CHARSET);
			prestr.append(key).append("=").append(value).append("&");
	    }
	    if(prestr.length() > 0){
	    	prestr.deleteCharAt(prestr.length() - 1);	               
	    }
	     return prestr.toString();
	} 
}
